<template>
  <div class="showBox" v-loading="loading"
       element-loading-text="加载中"
       element-loading-spinner="el-icon-loading"
       element-loading-background="rgba(255, 255, 255, 0.6)">
    <div class="operation" v-show="showType">
      <el-select size="mini" v-model="modelType" @change="getOrderModel" v-if="btnType" placeholder="请选择模板">
        <el-option v-for="(item,index) in quermodel" :key="index" :label="item.model" :value="item.orderId"></el-option>
      </el-select>
      <el-button type="success" :loading="saveLoad" size="mini" @click="saveAll('/order/receiveOrderMsg',1)">保 存
      </el-button>
      <el-button type="success" :loading="applyLoad" size="mini" @click="saveAll('/order/executeOrder',0)">执 行
      </el-button>
    </div>
    <!-- <div id="myDiagramDiv" style="margin-top: 20px"></div> -->
    <el-row class="m-drag">
        <el-col class="m-drag-left" v-show="isDeagLeft">
            <el-col class="m-drag-ele" :span='24'>服务组件</el-col>
            <el-col id="myPaletteDiv" style="height: 230px" :span='24'></el-col>
            <el-col class="m-drag-ele" :span='24'>资源组件</el-col>
            <el-col id="myPaletteServiceDiv" style="height: 150px" :span='24'></el-col>
            <el-col class="m-drag-ele" :span='24'>安全域</el-col>
            <el-col id="myPaletteSafeDiv" style="height: 150px" :span='24'></el-col>
        </el-col>
        <el-col id="myDiagramDiv" class="m-drag-region"></el-col>
    </el-row>
    <EditorFire ref="fireWall" :allData="targetFire" :allCreateVM="allCreateVM" :netWorkName="netWorkName"
                @fireData="fireData"></EditorFire>
    <EditorVpn ref="vpn" :allData="targetVpn" :allCreateVM="allCreateVM" :netWorkName="netWorkName"
               @vpnData="vpnData"></EditorVpn>
  </div>
</template>

<script>
    import "@/assets/go.js"
    import EditorFire from "./securityTopology/editorFirewall"
    import EditorVpn from "./securityTopology/editorVPN"
    import {init} from "@/assets/js/initTopology.js"
    var $ = go.GraphObject.make;
    export default {
        components: {
            EditorFire,
            EditorVpn
        },
        props: ['showData'],
        data() {
            return {
                showType:false,
                btnType: true,
                loading: false,
                dialogVisible: false,
                dialogSelect: false,
                dialogDevice: false,
                dialogDrawLink: false,
                saveLoad: false,
                applyLoad: false,
                vms: [],
                modelType: '',
                quermodel: [],
                source: null,
                domains: [],
                nodeArr: [],
                addDevice: [],
                addName: '',
                addtionVM: false,
                myDiagram: null,
                targetNode: {},
                targetFire: {},
                targetVpn: {},
                singleLink: {from: '', to: ''},
                operation: 0,
                netWorkName: [],
                allCreateVM: [],
                virtualDevice: [],
                vmArr: [],
                security: {
                    key: '',
                    vms: [],
                    accessNetwork: null,
                    cipherMachine: null,
                    domainId: null,
                    domainName: '',
                    domainType: "0",
                    elementCount: 1,
                    state: null,
                    stateMessage: null
                },
                myPalette: null, //资源组件模块
                myPaletteService: null, //服务组件模块
                myPaletteSafe: null, //安全域模块
                selectNode: {}, //流程图选中元素的数据
                isDeagLeft: true, //是否显示右侧元素
            }
        },
        mounted() {
            this.getnetwork()
            this.dataDocking()
        },
        methods: {
            initVms(showObj) {
                let id = showObj.typeId
                let isEdit = showObj.isEdit
                this.modelType = ''
                if (this.myDiagram) {
                    this.myDiagram.div = null
                    this.myPalette.div = null
                    this.myPaletteSafe.div = null
                    this.myPaletteService.div = null
                }
                if (id) {
                     this.btnType = false
                    if (isEdit == 0){
                        this.showType = false
                        this.isDeagLeft = false
                    }else {
                        this.showType = true
                        this.isDeagLeft = true
                    }
                }else{
                    this.isDeagLeft = true
                    this.showType = true
                    this.btnType = true
                }
                this.loading = true
                this.$http({
                    url: this.$http.adornUrl('/order/getAllResource'),
                    method: 'get',
                }).then(({data}) => {
                    this.loading = false
                    let arr = data.instanceList
                    arr.map(n => {
                        let o = {
                            vmId: n.instanceId,
                            vmName: n.instanceName,
                            cmpId: n.instanceIp
                        }
                        Object.assign(n, o)
                        delete n.disabled
                        delete n.instanceId
                        delete n.instanceName
                        delete n.instanceIp
                    })
                    this.virtualDevice = arr
                    if (id) {
                        this.$http({
                            url: this.$http.adornUrl(`/order/queryOrder/${id}`),
                            method: 'get'
                        }).then(({data}) => {
                            let source = data.order
                            this.source = source
                            this.parseData(source, showObj)
                        })
                    } else {
                        if (isEdit == 1){
                            this.vmArr =[]
                            this.domains = []
                            this.source = null
                            this.vms = []
                            init(this, this.virtualDevice, [], [], showObj)
                        }
                    }
                }).catch(error => {
                    this.disLoading = false
                    this.$message({
                        showClose: false,
                        message: '程序异常,请联系管理员',
                        type: 'warning'
                    })
                })
            },
            initShow(showObj) {
                this.$http({
                    url: this.$http.adornUrl('/order/queryModel'),
                    method: 'get',
                }).then(({data}) => {
                    this.quermodel = data.model
                }).catch(error => {
                    this.$message.error("请检查网络连接")
                })
                this.initVms(showObj)
            },
            parseData(source, showObj={}) {
                let chains = source.chains
                let domains = source.domains
                let nodeArr = []
                let linkArr = []
                chains.forEach(m => {
                    m.vnfs.map(n => {
                        let o = {
                            key: n.vnfId,
                            text: n.vnfId,
                            type: Number(n.vnfType) ? 'vpn' : 'firewall',
                            source: require(`@/assets/img/element/${Number(n.vnfType) ? 'vpn' : 'firewall'}.jpg`)
                        }
                        Object.assign(n, o)
                    })
                    m.links.map(n => {
                        let o = {
                            from: n.startId,
                            to: n.endId
                        }
                        Object.assign(n, o)
                    })
                    nodeArr.push(...m.vnfs)
                    linkArr.push(...m.links)
                })
                let serviceArr = []
                domains.map(n => {
                    n.vms.map(m => {
                        let o = {
                            key: m.cmpId,
                            text: m.cmpId,
                            type: "service",
                            group: n.domainId,
                            source: require(`@/assets/img/element/service.jpg`)
                        }
                        Object.assign(m, o)
                        nodeArr.push(m)
                        serviceArr.push(m)
                    })
                    let d = {
                        key: n.domainId,
                        text: n.domainId,
                        isGroup: true,
                        type: 'safe',
                        category: 'OfGroups'
                    }
                    Object.assign(n, d)
                    nodeArr.push(n)
                })
                this.domains = domains
                serviceArr.forEach(item => {
                    this.virtualDevice.forEach((n, k) => {
                        if (item.vmId === n.vmId) {
                            this.virtualDevice.splice(k, 1)
                        }
                    })
                })
                init(this, this.virtualDevice, nodeArr, linkArr, showObj)
            },
            switchImg(node) {
                return require(`@/assets/img/element/${node.type}.jpg`)
            },
            cancelLink() {
                this.singleLink = {from: '', to: ''}
                this.dialogDrawLink = false
            },
            fireData(obj) {
                let newObj = Object.assign({},obj)
                let name = newObj.firewall.firewallName
                var nodeData = this.myDiagram.model.findNodeDataForKey(name);
                nodeData.firewall = newObj.firewall
                nodeData.createVM = newObj.createVM
                this.myDiagram.model.updateTargetBindings(nodeData);
            },
            vpnData(obj) {
                let key = obj.vpn.vpnName
                var nodeData = this.myDiagram.model.findNodeDataForKey(key);
                nodeData.vpn = obj.vpn
                nodeData.createVM = obj.createVM
                this.myDiagram.model.updateTargetBindings(nodeData);
            },
            showDomain() {
                let stamp = (new Date()).getTime()
                this.security.key = `D${stamp}`
                this.security.domainId = `D${stamp}`
                this.security.domainName = `D${stamp}`
                this.dialogVisible = true
            },
            getOrderModel(orderid) { //获取模板信息
                this.$http({
                    url: this.$http.adornUrl(`/order/queryOrder/` + orderid),
                    method: 'get'
                }).then(({data}) => {
                    this.source = null
                    if(this.myDiagram) this.myDiagram.div = null
                    this.domains = []
                    let objArr = []
                    let source = data.order
                    let stamp = (new Date()).getTime()
                    source.domains.map((n,i) => {
                      let str = `D${stamp + 5*i}`
                      objArr.push({
                        old: n.domainId,
                        new: str
                      })
                      n.domainId = str,
                      n.domainName = str,
                      n.key = str
                    })
                    source.chains.map(w => {
                      w.links.map(m => {
                        objArr.forEach(k => {
                          if(m.startId == k.old) m.startId = k.new
                          if(m.endId == k.old) m.endId = k.new
                        })
                      })
                    })
                    this.source = source
                    this.parseData(this.source, {isEdit: 1})
                })
            },
            getnetwork() {
                this.$http({
                    url: this.$http.adornUrl('/vm/networkList'),
                    method: 'post'
                }).then(({data}) => {
                    if (data.list && data.list.length) {
                        this.netWorkName = data.list
                    }
                }).catch(error => {
                    this.$message({
                        showClose: false,
                        message: '程序异常,请联系管理员',
                        type: 'warning'
                    })
                })
            },
            dataDocking() { // 接口获取规则配置数据
                this.$http({
                    url: this.$http.adornHardWareUrl('/generator/deploy/listAll'),
                    method: 'get',
                    params: this.$http.adornParams()
                }).then(({data}) => {
                    if (data && data.code == '0') {
                        let arr = []
                        data.all.forEach(n => {
                            let obj = {
                                vcpusNeed: n.cpu,
                                hostId: n.dcId,
                                hostName: n.osType,
                                tmpId: n.did,
                                diskGbNeed: n.disk,
                                dname: n.dname,
                                reProduce: !!n.isCrossDc,
                                memoryNeed: n.memory
                            }
                            arr.push(obj)
                        })
                        this.allCreateVM = [...arr]
                    }
                })
            },
            saveAll(url, sta) {
                this.loading = true;
                if (this.myDiagram) {
                    let obj = JSON.parse(this.myDiagram.model.toJson())
                    let link = obj.linkDataArray, node = obj.nodeDataArray
                    let start = link.filter(item => item.from.indexOf('D') >= 0)
                    let orderLink = []
                    let chains = []
                    start.forEach(s => {
                        let one = []
                        one.push(s)
                        for (let i = 0; i < one.length; i++) {
                            link.forEach(n => {
                                if (n.from == one[one.length - 1].to) {
                                    one.push(n)
                                    if (n.to.indexOf('D') >= 0) return
                                }
                            })
                        }
                        orderLink.push(one)
                    })
                    orderLink.forEach(k => {
                        let vnfs = []
                        let flagArr = [...k]
                        flagArr.shift()
                        flagArr.map((n, j) => {
                            let item = node.filter(m => m.key == n.from)[0]
                            item.vnfId = item.text
                            item.vnfIndex = j
                            if (item.type === 'vpn') {
                                item.vnfType = '1'
                            }else {
                                item.vnfType = '0'
                            }
                            delete item.text
                            delete item.source
                            delete item.key
                            delete item.type
                            vnfs.push(item)
                        })
                        k.map(n => {
                            let m = {
                                startId: n.from,
                                isStart: i == 0,
                                endId: n.to,
                                isEnd: i == orderLink.length - 1
                            }
                            Object.assign(n, m)
                            delete n.from
                            delete n.to
                            delete n.points
                        })
                        let i = k.length - 1
                        let object = {
                            chainId: null,
                            endDomainId: k[i].endId,
                            links: k,
                            startDomainId: k[0].startId,
                            state: null,
                            stateMessage: null,
                            vnfs: vnfs
                        }
                        chains.push(object)
                    })
                    let domains = node.filter(n => n.type == 'safe')
                    let seviceArr = node.filter(n => n.type == 'service')
                    domains.map(n => {
                        delete n.key
                        delete n.isGroup
                        delete n.text
                        delete n.type
                        delete n.category
                        n.vms = []
                        seviceArr.forEach((item, k) => {
                            if (n.domainId === item.group) {
                                n.vms.push(item)
                            }
                        })
                        n.elementCount = n.vms.length
                        n.vms.map(m => {
                            delete m.key
                            delete m.group
                            delete m.type
                            delete m.source
                            delete m.text
                        })
                    })
                    let urlQuery = this.$route.query.id
                    let totleData = {
                        actionType: urlQuery ? 1 : 0,
                        inuse: false,
                        orderId: this.source && this.source.orderId || "",
                        sequenceId: this.source && this.source.sequenceId || "",
                        serviceId: this.source && this.source.serviceId || null,
                        state: "",
                        stateMessage: null,
                        updatetime: (new Date()).getTime(),
                        userId: this.$store.state.user.id,
                        chains: chains,
                        domains: domains
                    }
                    // console.log(totleData, JSON.stringify(totleData),'totleData')
                    // return
                    this.$http({
                        url: this.$http.adornUrl(url),
                        method: 'post',
                        data: this.$http.adornData(totleData, false)
                    }).then(({data}) => {
                        this.loading = false;
                        console.log(data.code, "code")
                        if (data.code != 0){
                            this.$confirm(data.msg, '提示', {
                                confirmButtonText: '确定',
                                cancelButtonText: '取消',
                                type: 'warning'
                            }).then(() => {
                                // sta ? this.saveLoad = false : this.applyLoad = false;
                            }).catch(() => {
                            });
                        }else {
                            // sta ? this.saveLoad = false : this.applyLoad = false;
                          this.$emit('showDialog',false)
                        }
                    })
                }
            }
        }
    }
</script>

<style scoped lang="scss">
.m-drag{
    display: flex;
    .m-drag-left{
        width: 400px;
        border: 1px solid darkgray;
    }
    .m-drag-region{
        width: 100%;
        margin-left: 10px;
        border: 1px solid darkgray;
    }
    .m-drag-ele{
        background-color: darkgray;
        text-align: center;
        font: bold 14px sans-serif;
        width: 100%;
        height: 30px;
        line-height: 30px;
    }
}

  .showBox {
    #myDiagramDiv {
      /*height: 100%;//500px;*/
      height: 650px;
    //   width: 100%;
    }

    .operation {
      width: 100%;
      height: 44px;
      padding-bottom: 20px;
      .el-button {
        float: left;
        margin-right: 10px;
      }
    }
  }
</style>
